/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#ifndef INCLUDE_SHADER_LINE
#define INCLUDE_SHADER_LINE

#include "shader_built_in_functions.h"
#include "shader_color.h"
#include "shader_binding_ID.h"



struct S_MeshTranformProp {
	//虚线
	float m_DottedLine;
	//距离渐变
	float m_Remote;
	
	//缩放
	float m_Scale;

	//X
	float m_XScale;
	//Y
	float m_YScale;
	//Z
	float m_ZScale;

	//X
	float m_XMove;
	//Y
	float m_YMove;
	//Z
	float m_ZMove;

	//亮度
	float m_Intensity;

	//深度缩放
	float m_DepthScale;

	//是否朝向镜头
	int m_TransformMode;

	uint m_Color;
	uint m_Activate;

};

struct S_LineCoord {
	vec2 coord;
	vec2 weights;
};


#define DEF_LINKLINE_TYPE_CircleTangent_V 0
#define DEF_LINKLINE_TYPE_CircleTangent_H 1
#define DEF_LINKLINE_TYPE_StraightLine    2
#define DEF_LINKLINE_TYPE_C               3





#ifdef __cplusplus

#include <basic_vec.h>


// GLSL Type
using uint = unsigned int;
using uint64_t = uint64;
#define inout

Inline S_MeshTranformProp MeshProp_Init() {
	static S_MeshTranformProp p = {
		1, 1,   1,    1, 1, 1,    0, 0, 0,    1, 1, 0,    0
	};
	return p;
}


#define DEF_Cal_CutCircleNum float f_glsl_Cal_CutCircleNum(vec2 begin, vec2& end, int dir, float& radius, float& maxRadius) 

#else


#define DEF_Cal_CutCircleNum float f_glsl_Cal_CutCircleNum(vec2 begin, inout vec2 end, int dir, inout float radius, inout float maxRadius) 

#endif



//计算园公切线旋转角度数量
Inline DEF_Cal_CutCircleNum {
	vec2 size = end - begin;

	float PN;
	float al = radius;
	float angle = 0;
	//vec2 perpendicular;
	vec3 rot_dir; rot_dir.x = 0; rot_dir.y = 0; rot_dir.z = 1;

	vec3 perpendicular;

	switch (dir) {
	case DEF_LINKLINE_TYPE_CircleTangent_V: {
		PN = sign(size.x);

		begin.x += al * PN;
		
		if (abs(size.x) < maxRadius*2 && size.y < 0) {
			al = maxRadius;
			radius = maxRadius;
			end.x += al * PN;
			maxRadius = -1;
			
		}
		else {
			radius = al;
			end.x -= al * PN;
			maxRadius = 1;
		}

		size = end - begin;

		float cl = length(size);
		float sinA = sin(al * 2 / cl);
		float bl = cos(al * 2 / cl) * cl;

		
		vec4 quat = f_graph_vec_build_quat(rot_dir, sinA * PN);

		vec2 nor_size = normalize(-size);
		rot_dir.x = nor_size.x;
		rot_dir.y = nor_size.y;
		rot_dir.z = 0;
		rot_dir = f_graph_quatTranformInv(quat, normalize(rot_dir) * bl);

		nor_size.x = rot_dir.x;
		nor_size.y = rot_dir.y;

		nor_size += end;
		nor_size -= begin;
		nor_size = normalize(nor_size);
		perpendicular.x = nor_size.x;
		perpendicular.y = nor_size.y;
		perpendicular.z = 0;

		rot_dir.x = -1 * PN; rot_dir.y = 0; rot_dir.z = 0;
		angle = f_graph_vec_to_radians_180(perpendicular, rot_dir);

		rot_dir.x = 0; rot_dir.y = 1; rot_dir.z = 0;
		break;
	}
	case DEF_LINKLINE_TYPE_CircleTangent_H: {
		PN = sign(-size.y);

		begin.y -= al * PN;
		if (abs(size.y) < maxRadius*2 && size.x < 0) {
			al = maxRadius;
			radius = maxRadius;
			end.y -= al * PN;
			maxRadius = -1;
		}
		else {
			radius = al;
			end.y += al * PN;
			maxRadius = 1;
		}
		
		size = end - begin;

		float cl = length(size);
		float sinA = sin(al * 2 / cl);
		float bl = cos(al * 2 / cl) * cl;


		vec4 quat = f_graph_vec_build_quat(rot_dir, sinA * PN);

		vec2 nor_size = normalize(-size);
		rot_dir.x = nor_size.x;
		rot_dir.y = nor_size.y;
		rot_dir.z = 0;
		rot_dir = f_graph_quatTranformInv(quat, rot_dir * bl);

		nor_size.x = rot_dir.x;
		nor_size.y = rot_dir.y;

		nor_size += end;
		nor_size -= begin;
		nor_size = normalize(nor_size);
		perpendicular.x = nor_size.x;
		perpendicular.y = nor_size.y;
		perpendicular.z = 0;

		rot_dir.x = 0; rot_dir.y = 1 * PN; rot_dir.z = 0;
		angle = f_graph_vec_to_radians_180(perpendicular, rot_dir);

		rot_dir.x = 1; rot_dir.y = 0; rot_dir.z = 0;
		break;
	}
	}

	if (dot(perpendicular, rot_dir) < 0) {
		angle += (M_PI - angle) * 2;
	}
	return angle;
}



#endif